<?php
/**
 * <https://y.st./>
 * Copyright © 2019 Alex Yst <mailto:copyright@y.st>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org./licenses/>.
**/

$xhtml = array(
	'<{title}>' => 'Unlimited counting',
	'takedown' => '2017-11-01',
	'<{body}>' => <<<END
<img src="/img/CC_BY-SA_4.0/y.st./weblog/2019/08/11.jpg" alt="Flowers growing in a small, raised flowerbed" class="framed-centred-image" width="800" height="480"/>
<section id="dreams">
	<h2>Dream journal</h2>
	<p>
		I dreamed I got another flat tire.
		I was so frustrated, as I was out when it happened, which made it a pain to deal with, but also because I&apos;m out of spare inner tubes.
		When I took the tire off and looked at the tube, it had at least two holes in it.
		I was confused as to how that had happened.
		After the first hole, the tire should have deflated and not provided the resistance needed to puncture a second hole.
		These were pretty large holes too; there&apos;s no way the air would have drained slowly.
		After spotting the second hole though, I wondered if maybe there was a third hole, but I didn&apos;t go looking for it.
		One hole or twenty, the tube was out of commission until I could find time to patch it.
	</p>
</section>
<section id="diet">
	<h2>Dietary intake</h2>
	<p>
		For breakfast, I had 79 grams of cereal and 179 grams of soy milk.
		For lunch, I had a 453-gram smoothie.
		For dinner, I had a veggie patty, tapioca cheese, and pickle sandwich.
		I also snacked on 447 grams of pretzels throughout the day.
	</p>
</section>
<section id="Sunday">
	<h2>It&apos;s Sunday.</h2>
	<p>
		I debated back and forth as to whether to spend my morning on errands, such as dropping off my coins at the credit union to lighten my wallet&apos;s load.
		I mean, I should probably skip that for now and focus on my reading assignments, right?
		In the end, I decided I had plenty of time to read later in the week, and that I really need the exercise, so I headed to the credit union, my first errand.
		I was nearly there when I remembered it was Sunday, and it&apos;d be closed.
		So much for that then.
		I&apos;ll have to go tomorrow instead.
		Still, I&apos;m glad I didn&apos;t realise at first.
		That got me out of the apartment and moving my legs for a bit, which is something I need more than study time this week.
		I mean, I was also going to need to bike to work, so it wasn&apos;t like I wasn&apos;t going to meet my daily biking goal already, but I feel like I&apos;ve been overeating a bit lately, and this helps balance that out a bit.
	</p>
</section>
<section id="drudgery">
	<h2>Drudgery</h2>
	<p>
		My discussion posts for the day:
	</p>
	<blockquote>
		<p>
			If you look at the discussion assignment, the professor specifically mentions <code>TextView</code>.
			That gives us context as to what is meant when we are asked to talk about widgets.
			<code>TextView</code> is the kind of widget that is used in the definition of an activity, so we&apos;re talking about activity widgets, and not home screen widgets.
			This is made even more clear when the assignment asks us to describe two uses for each widget <strong>*in*</strong> an Android application.
			You mention widgets allowing you to skip opening the application altogether, showing that they&apos;re not in the application, though they are a part of an application.
		</p>
	</blockquote>
	<blockquote>
		<p>
			You listed a number of home screen widgets, but this discussion assignment isn&apos;t about home screen widgets.
			If you look at what is asked, we&apos;re asked about widgets <strong>*in applications*</strong>, not on the home screen.
			Furthermore, the discussion assignment specifically mentions <code>TextView</code>, a widget that would never appear on the home screen.
			Instead, it&apos;s used in the definition of an Android activity.
			The discussion is about activity widgets.
			We actually haven&apos;t even read about home screen widgets in this course.
		</p>
	</blockquote>
</section>
<section id="Minetest">
	<h2>Minetest</h2>
	<img src="/img/CC_BY-SA_3.0/minetest.net./weblog/2019/08/11.png" alt="A rock wall that needs to be bored through" class="framed-centred-image" width="1024" height="600"/>
	<p>
		I came up with an idea of how to remove the hard cap on mining counts in <code>liblevelup</code>.
		Currently, if you go over the maximum, you roll back over to zero.
		It&apos;s like integer overflow, except that we&apos;re working with floats, as integers aren&apos;t available for our use, and the overflow mechanic was deliberately programmed instead of simply being a result of truncation.
		The only alternatives I knew of at the time were either a hard cap, at which items stopped being counted due to precision loss, or a smaller range with actual overflow provided by the Minetest engine when saving floats through the integer-type-saving interface.
		I absolutely didn&apos;t want the hard cap.
		The overflow was a must, because a sudden drop in score would alert me to the fact that a range problem had occurred, not to mention that I could precisely fix the data after extending the range, by adding a very specific and known number to the then-current count in the database.
		In other words, the effects of running out of range would be completely reversible.
		As for the smaller range and automatic overflow, I was worried the smaller range wouldn&apos;t be large enough.
		I mean, it&apos;d be a range from zero to 4 294 967 295, but if you played the game long enough, I worried that wouldn&apos;t be enough.
		In retrospect, that&apos;s probably <strong>*way*</strong> more than enough.
		But at this point, I&apos;m way too deep in trying to get the most range out of this thing.
		Anyway, my plan to extend the range again if absolutely need be was to add a second counter per stat, that counted how many times overflow occurred.
		It would be like doubling the number of bits, except that we&apos;re not working with an even number of bits due to working with floats instead of true integers.
		This second counter would reside in a second entry in the database.
		Now though, I&apos;ve got an even better idea.
		First, limit the first counter to the number of digits it can fully represent instead of packing it full of the widest range of values it can hold.
		Leave out negative values.
		Next, when incrementing the value, we already have to retrieve the current value first, which is stored as a string instead of an integer, so we can check the length of the string before doing anything else.
		If it&apos;s too long, take the last however many digits we&apos;ve decided can be fully utilised and increment that instead of the whole number.
		If it doesn&apos;t pass the limit, concatenate the number with the part of the string we cut off.
		Otherwise, cut off the next segment of the same length and increment that, replacing the overflowing number with a string of however many zeros would fill the length.
		This can be done recursively until either no overflow occurs or we run out of digit segments, and if the latter, we can add a new segment at the beginning that is simply set to <code>&quot;1&quot;</code>.
		Dynamically, the number is extended as necessary, and the number of counters need not be known at any time.
		When retrieving the value instead of incrementing it, we just cast the string to a number as usual.
		Precision is lost, but the number returned is as close as can be properly represented.
	</p>
	<p>
		We don&apos;t need this feature.
		At all.
		But it&apos;d give me peace of mind knowing that this potential problem has been solved once and for all.
		I might add a setting though that lets you use the simpler back-end of real overflow instead of my infinite range solution for saving system resources.
		I&apos;m not leaving in my current middle-ground solution though, as for the range that nearly everyone will be in, only one extra check is performed, which is exactly how many extra checks are needed in the current solution&apos;s false overflow mechanism.
		The built-in solution is probably more efficient, but my current solution has nothing on my new solution.
		I suppose implementing this infinite counter (well, not <em>*infinite*</em>, as it&apos;s still limited by $a[RAM]) will be my next coding project before I get back to work on <code>alchemy</code>.
	</p>
</section>
END
);
